use bytes::Bytes;
use reqwest::Client;

use crate::common::{query_url, Response, WxErr};

use super::param::{
    DomainInfoReq, DomainInfoRes, FallbackReq, FallbackRes, JsErr, JsErrDetailReq, JsErrDetailRes,
    JsErrRes, MediaReq, Performance, PerformanceRes, ReleasePlan, SceneRes, UserLogReq, UserLogRes,
    VersionList,
};

pub async fn get_domain_info<T>(
    token: T,
    req: &DomainInfoReq,
) -> Result<Response<DomainInfoRes>, reqwest::Error>
where
    T: AsRef<str>,
{
    let url = query_url("https://api.weixin.qq.com/wxa/getwxadevinfo", token);
    let client = Client::new();
    client
        .post(url)
        .json(req)
        .send()
        .await?
        .json::<Response<DomainInfoRes>>()
        .await
}

pub async fn get_performance<T>(
    token: T,
    req: &Performance,
) -> Result<Response<PerformanceRes>, reqwest::Error>
where
    T: AsRef<str>,
{
    let url = query_url(
        "https://api.weixin.qq.com/wxaapi/log/get_performance",
        token,
    );
    let client = Client::new();
    client
        .post(url)
        .json(req)
        .send()
        .await?
        .json::<Response<PerformanceRes>>()
        .await
}

pub async fn get_scene_list<T>(token: T) -> Result<Response<SceneRes>, reqwest::Error>
where
    T: AsRef<str>,
{
    let url = query_url("https://api.weixin.qq.com/wxaapi/log/get_scene", token);
    let client = Client::new();
    client
        .get(url)
        .send()
        .await?
        .json::<Response<SceneRes>>()
        .await
}

pub async fn get_version_list<T>(token: T) -> Result<Response<VersionList>, reqwest::Error>
where
    T: AsRef<str>,
{
    let url = query_url(
        "https://api.weixin.qq.com/wxaapi/log/get_client_version",
        token,
    );
    let client = Client::new();
    client
        .get(url)
        .send()
        .await?
        .json::<Response<VersionList>>()
        .await
}

pub async fn get_user_log<T>(
    token: T,
    req: &UserLogReq,
) -> Result<Response<UserLogRes>, reqwest::Error>
where
    T: AsRef<str>,
{
    let url = query_url(
        "https://api.weixin.qq.com/wxaapi/userlog/userlog_search",
        token,
    );
    let client = Client::new();
    client
        .get(url)
        .json(req)
        .send()
        .await?
        .json::<Response<UserLogRes>>()
        .await
}

pub async fn get_fallback<T>(
    token: T,
    req: &FallbackReq,
) -> Result<Response<FallbackRes>, reqwest::Error>
where
    T: AsRef<str>,
{
    let url = query_url("https://api.weixin.qq.com/wxaapi/feedback/list", token);
    let client = Client::new();
    client
        .get(url)
        .json(req)
        .send()
        .await?
        .json::<Response<FallbackRes>>()
        .await
}

pub async fn get_media<T>(token: T, req: &MediaReq) -> Result<Response<Bytes>, reqwest::Error>
where
    T: AsRef<str>,
{
    let url = query_url(
        "https://api.weixin.qq.com/cgi-bin/media/getfeedbackmedia",
        token,
    );
    let client = Client::new();
    let res = client.get(url).json(req).send().await?;
    if res.status().is_success() {
        Ok(Response::Ok(res.bytes().await?))
    } else {
        Ok(Response::Err(res.json::<WxErr>().await?))
    }
}

// TODO: 该接口用于查询JS错误详情
pub async fn get_jserr_list<T>(token: T, req: &JsErr) -> Result<Response<JsErrRes>, reqwest::Error>
where
    T: AsRef<str>,
{
    let url = query_url("https://api.weixin.qq.com/wxaapi/log/jserr_list", token);
    let client = Client::new();
    client
        .post(url)
        .json(req)
        .send()
        .await?
        .json::<Response<JsErrRes>>()
        .await
}

pub async fn get_jserr<T>(
    token: T,
    req: &JsErrDetailReq,
) -> Result<Response<JsErrDetailRes>, reqwest::Error>
where
    T: AsRef<str>,
{
    let url = query_url("https://api.weixin.qq.com/wxaapi/log/jserr_detail?", token);
    let client = Client::new();
    client
        .post(url)
        .json(req)
        .send()
        .await?
        .json::<Response<JsErrDetailRes>>()
        .await
}

pub async fn get_release_plan<T>(token: T) -> Result<Response<ReleasePlan>, reqwest::Error>
where
    T: AsRef<str>,
{
    let url = query_url("https://api.weixin.qq.com/wxa/getgrayreleaseplan", token);
    let client = Client::new();
    client
        .get(url)
        .send()
        .await?
        .json::<Response<ReleasePlan>>()
        .await
}
